<?php

if (!defined('codeark.google-analytics-generator'))
	throw new Exception('missing dependency: google-analytics-generator.class.php');
		
class ABTest implements IGoogleAnalyticsVariable {

	private $name;	
	private $testCases;
	private $totalTestCasesWeight = 0;
	private $defaultTestCase = false;
	private $current = false;
	
	function __construct($name, $defaultTestCase, $testCases = array()) {
		
		$this->name = $name;
		
		$this->defaultTestCase = $defaultTestCase;		
						
		$this->testCases = $testCases;
		
		$len = sizeof($this->testCases);
		
		for ($i = 0; $i < $len; $i++)
			$this->addTestCase($this->testCases[$i]);	
	}

	function addTestCase($testCase) {
		
		if ($this->totalTestCasesWeight == 100){
			trigger_error('failed to add a test case due to full capacity');
			return false;
		}
		
		$weight = $testCase->getWeight();
		$name = $testCase->getName();
		
		if ($weight <= 0) {
			trigger_error("Invalid weight $weight for test case $name");
			return false;
		}
		
		$tempTotal = $this->totalTestCasesWeight + $weight;
		
		if ($tempTotal > 100) {
			trigger_error("Unable to add test case $name, weight is too high. Try reducing it to {100 - $this->totalTestCasesWeight}");
			return false;
		}

		$this->totalTestCasesWeight = $tempTotal;
		
		$this->testCases[$name] = $testCase;

		return sizeof($this->testCases) - 1;
	}
	
	function removeTestCase($testCase) {		
		$this->totalTestCasesWeight -= $testCase.getWeight();		
		unset($this->testCases[$testCase->getName()]);	
	}

	function rollTheDice() {
				
		if ($this->totalTestCasesWeight == 0) {
			$this->current = $this->defaultTestCase;			
			return $this->current;
		}
		
		$roll = rand(1, 100);
		
		if ($roll > $this->totalTestCasesWeight) {			

			$this->current = $this->defaultTestCase;
		
		} else {
			
			$len = sizeof($this->testCases);
			$weight = 0;
			
			foreach ($this->testCases as $key => $testCase) {			
		
				$weight += $testCase->getWeight();
				
				if ($roll <= $weight) {
					$this->current = $testCase;
					break;					
				}
			}

			// if we're here then something bad happened, since case $roll > $totalTestCasesWeight is covered
			if (!$this->current)			
				throw new Exception("something bad has happened when it shouldn't have");
		}
		
		return $this->current;
	}
	
	function render() {		
		echo $this->current->getCode();
	}

	function getCurrent() {
		return $this->current;
	}

	/* IGoogleAnalyticsVariable Implementation */
	
	function getName() {
		return "abtest_{$this->name}";
	}
	
	function getValue() {
		//the name of the ab test currently displayed (assuming rollthedice())
		if (!$this->current)
			throw new Exception('need to call rollTheDice() first');
			
		return $this->current->getName();
	}
	
	function getOptScope() {
		return 3;
	}
	
	/* IGoogleAnalyticsVariable Implementation */
}

class TestCase {

	private $code;
	private $name;
	private $weight;

	function __construct($name, $weight, $code) {
		$this->name = $name;		
		$this->code = $code;
		$this->weight = $weight;
	}

	function getCode() {
		return $this->code;
	}

	function getName() {
		return $this->name;
	}
	
	function getWeight() {
		return $this->weight;
	}
}
?>